package com.wobito.controller.admin;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wobito.common.constants.BaseResponse;
import com.wobito.common.constants.BusinessException;
import com.wobito.common.constants.ErrorCode;
import com.wobito.common.constants.TableDataInfo;
import com.wobito.common.utils.*;
import com.wobito.common.utils.uuid.IdUtils;
import com.wobito.pojo.bean.Cabinet;
import com.wobito.pojo.bean.Person;
import com.wobito.pojo.dto.person.PersonDTO;
import com.wobito.pojo.enums.PersonStatusEnum;
import com.wobito.pojo.mqtt.MQTTBean;
import com.wobito.pojo.mqtt.MQTTContext;
import com.wobito.pojo.mqtt.MQTTInfo;
import com.wobito.pojo.vo.person.AddPersonVO;
import com.wobito.pojo.vo.person.PersonVO;
import com.wobito.service.IBorrowReturnLogService;
import com.wobito.service.IBorrowService;
import com.wobito.service.ICabinetService;
import com.wobito.service.IPersonService;
import com.wobito.system.aspect.OperLog;
import com.wobito.system.mqtt.MQTTServer;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * @Author Wangbaba
 * @Date 2024/8/27 17:28
 * @Version 1.0
 */
@RestController
@RequestMapping("/manage/personManage")
@Api(tags = "借阅人管理")
public class PersonManageConroller {

    @Autowired
    private MQTTServer mqttServer;
    @Autowired
    private IPersonService personService;
    @Autowired
    private IBorrowService borrowService;
    @Autowired
    private ICabinetService cabinetService;
    @Autowired
    private IBorrowReturnLogService borrowReturnLogService;

    @GetMapping()
    @ApiOperation(value = "根据条件查询借阅人信息")
    @OperLog(thing = "根据条件查询借阅人信息")
    @PreAuthorize("hasAnyRole('SUPER_ADMIN','NOMAL_ADMIN')")
    public BaseResponse getPersonList(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                      @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
                                      @RequestParam(value = "queryName", required = false) String queryName,
                                      @RequestParam(value = "isDeleted", required = false) Integer isDeleted) {
        TableDataInfo dataInfo = new TableDataInfo();
        PageHelper.startPage(pageNum, pageSize);
        List<PersonDTO> personDTOS = personService.selectPersonList(new PersonVO(queryName, isDeleted));
        dataInfo.setRows(personDTOS);

        dataInfo.setTotal(new PageInfo(personDTOS).getTotal());
        return ResultUtils.success(dataInfo);
    }

    @GetMapping("/getPersonBorrow/{id}")
    @ApiOperation(value = "根据借阅人ID获取当前借阅情况")
    @OperLog(thing = "根据借阅人ID获取当前借阅情况")
    @PreAuthorize("hasAnyRole('SUPER_ADMIN','NOMAL_ADMIN')")
    public BaseResponse getPersonBorrow(@PathVariable("id") Long id) {
        return ResultUtils.success(borrowService.selectBorrowByPerson(id));
    }

    @GetMapping("/getPersonBorrowLog/{id}")
    @ApiOperation(value = "根据借阅人ID获取借阅日志")
    @OperLog(thing = "根据借阅人ID获取借阅日志")
    @PreAuthorize("hasAnyRole('SUPER_ADMIN','NOMAL_ADMIN')")
    public BaseResponse getPersonBorrowLog(@PathVariable("id") Long id) {
        return ResultUtils.success(borrowReturnLogService.selectBookBorrowReturnByPersonId(id));
    }

    @PutMapping()
    @ApiOperation(value = "添加借阅人")
    @OperLog(thing = "添加借阅人")
    @PreAuthorize("hasAnyRole('SUPER_ADMIN','NOMAL_ADMIN')")
    public BaseResponse addPerson(@Valid AddPersonVO addPersonVO){
        if (addPersonVO.getFaceImage() == null || addPersonVO.getFaceImage().isEmpty()) {
            throw new BusinessException(ErrorCode.NULLPARAMS_ERROR, "人脸图片不能为空");
        }
        if (!ArrayUtil.contains(MimeTypeUtils.IMAGE_EXTENSION, FileTypeUtils.getFileType(addPersonVO.getFaceImage().getOriginalFilename()))) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "上传的文件类型不支持,仅可上传{bmp, gif, jpg, jpeg, png}格式");
        }
        Cabinet cabinet = cabinetService.getById(addPersonVO.getCabinetId());
        if (ObjectUtil.isNull(cabinet)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "柜子不存在!");
        }
        if (StringUtils.isEmpty(cabinet.getCameraId())) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "柜子未绑定摄像头!");
        }
        if (StringUtils.isEmpty(addPersonVO.getIcCode())){
            addPersonVO.setIcCode(ValidateCodeUtils.generateValidateCode4String(6));
        }
        //编译人脸
        String faceImage = MultipartFileToBase64Util.multipartFileToBase64(addPersonVO.getFaceImage());
        Person person = new Person(addPersonVO.getName(), addPersonVO.getIcCode(),cabinet.getId());
        MQTTBean MQTTBean = new MQTTBean("mqtt/face/" + cabinet.getCameraId(), getFaceByPerson(person, faceImage));
        //加锁，一个摄像头同一时刻只能添加一个人
        synchronized (LockUtils.getLock(LockUtils.MQTT_CAMERA_LOCK + cabinet.getCameraId())) {
            mqttServer.publish(MQTTBean);
        }
        boolean result = personService.save(person);
        if (!result) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "借阅人信息添加失败!");
        }
        return ResultUtils.successJSON("借阅人信息添加成功");
    }


    @PutMapping("/{id}")
    @ApiOperation(value = "手动启用借阅人")
    @OperLog(thing = "手动启用借阅人")
    @PreAuthorize("hasAnyRole('SUPER_ADMIN','NOMAL_ADMIN')")
    public BaseResponse enablePerson(@PathVariable("id") Long id) {
        return ResultUtils.success(personService.updateById(new Person(id, PersonStatusEnum.NORMAL.getCode())));
    }


    @DeleteMapping("/{id}")
    @ApiOperation(value = "手动锁定借阅人")
    @OperLog(thing = "手动锁定借阅人")
    @PreAuthorize("hasAnyRole('SUPER_ADMIN','NOMAL_ADMIN')")
    public BaseResponse lockList(@PathVariable("id") Long id) {
        return ResultUtils.success(personService.updateById(new Person(id, PersonStatusEnum.ABNOEMAL.getCode())));
    }

    private String getFaceByPerson(Person person, String faceImage) {
        MQTTContext mqttContext = new MQTTContext();
        mqttContext.setOperator("EditPerson");
        MQTTInfo mqttInfo = new MQTTInfo(String.valueOf(person.getIcCode()), person.getName(), faceImage);
        mqttContext.setInfo(mqttInfo);
        mqttContext.setMessageId(IdUtils.fastSimpleUUID());
        return JSON.toJSONString(mqttContext);
    }
}
